﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Data;
using CodeC.Interfaces;
using System.Xml.Linq;
using System.IO;
using CodeC.Models;
using System.ComponentModel.Composition;

namespace CodeC.Utilities
{
    /// <summary>
    /// This class handles XML file operations
    /// </summary>
    [Export]
    public class XMLFileOperations
    {
        #region Private Variables

        string _fileName = @"CodeCDatabase.xml";
        private FileOperations _fileOperations; 
        #endregion

        #region ctor

        [ImportingConstructor]
        public XMLFileOperations(FileOperations fileOperations)
        {
            _fileOperations = fileOperations;
        } 
        #endregion

        /// <summary>
        /// This method write the CodeCModel content into .codec extension.
        /// </summary>
        /// <param name="fileModel"></param>
        /// <returns></returns>
        public ICodeCFileModel Write(ICodeCFileModel fileModel)
        {
            _fileName = _fileOperations.CreateXMLDB(_fileName);

            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.Load(_fileName);

            XmlNode root = xmlDoc.DocumentElement;

            if (fileModel.ID == 0)
            {
                fileModel.ID = (MaxID() + 1);
                XmlElement elem = xmlDoc.CreateElement("CODECFILE");
                elem.AppendChild(xmlDoc.SetXmlElement("ID", fileModel.ID.ToString()));
                elem.AppendChild(xmlDoc.SetXmlElement("NAME", fileModel.Name));
                elem.AppendChild(xmlDoc.SetXmlElement("FILE", fileModel.File));
                root.AppendChild(elem);
                xmlDoc.Save(_fileName);
            }
            return fileModel;
        }

        /// <summary>
        /// This method delete content mentioned in CodeCModel
        /// </summary>
        /// <param name="fileModel"></param>
        /// <returns></returns>
        public bool Delete(ICodeCFileModel fileModel)
        {
            _fileName = _fileOperations.CreateXMLDB(_fileName);

            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.Load(_fileName);

            XmlNode root = xmlDoc.DocumentElement;

            if (fileModel.ID > 0)
            {
                XmlNode xmlNode = null;

                foreach (XmlNode item in root.ChildNodes)
                {
                    if (null != xmlNode) break;
                    foreach (XmlNode childItem in item.ChildNodes)
                    {
                        if (childItem.Name == "ID"
                            && childItem.InnerText == fileModel.ID.ToString())
                        {
                            xmlNode = item;
                            break;
                        }
                    }
                }
                root.RemoveChild(xmlNode);
            }

            xmlDoc.Save(_fileName);
            return true;
        }

        /// <summary>
        /// This method return Max ID
        /// </summary>
        /// <returns></returns>
        private int MaxID()
        {
            dynamic maxID;
            try
            {

                maxID = XDocument.Load(_fileName)
                                      .Elements().Select(
                                                  x => x.Elements("CODECFILE").Select(y => Convert.ToInt16(y.Element("ID").Value.ToString())).ToList().Max()
                                                         ).FirstOrDefault();

            }
            catch (Exception)
            {
                maxID = 0;
            }
            return maxID;
        }

        /// <summary>
        /// This method read the codecdb xml file and returns the list of CodeCFileModel
        /// </summary>
        /// <returns></returns>
        public List<ICodeCFileModel> Read()
        {
            _fileName = _fileOperations.CreateXMLDB(_fileName);

            var xmlProjectLogin = XDocument.Load(_fileName)
                                    .Elements().Select(
                                    x => x.Elements("CODECFILE").Select(
                                        y => new CodeCFileModel
                                            {
                                                ID = Convert.ToInt16(y.Element("ID").Value.ToString()),
                                                Name = y.Element("NAME").Value.ToString(),
                                                File = y.Element("FILE").Value.ToString()
                                            }
                                        ).ToList<ICodeCFileModel>()
                                    ).FirstOrDefault();

            return xmlProjectLogin;

        }
    }
}
